package com.atguigu.gulimall.gateway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

/**
 * @Title: GulimallCorsConfig
 * @Author whisper
 * @Package com.atguigu.gulimall.gateway.config
 * @Date 2025/7/21 18:25
 * @description: 网关统一配置跨域
 */
@Configuration //写代码第1步,标注他是一个配置类
public class GulimallCorsConfig {
    //写一个filter,我们所有的请求一进来以后放行,然后在他执行完了以后,返回给浏览器之前,我们给响应里面添加上支持跨域的字段就可以了
    //而且这个filter不用写在每一个项目里面,因为最终每一个项目可能都会被远程访问,进行跨域,我们只需要在网关(gateway)里面统一配置即可,
    //因为我们现在是网关代理给其他的服务,所以我们直接在网关里面统一配置跨域就可以解决这个问题

    //我们想要跨域呢,其实Springboot为我们提供了一个filter: CorsWebFilter,我们只需要将这个filter放到容器中,他就会产生作用
    @Bean //第8步: 加入容器中
    //第2步: 写一个方法,这个方法返回跨域的filter
    public CorsWebFilter corsWebFilter(){
        //第4步: 把跨域的配置信息构造出来(我们引入的是reactive(响应式编程)包下的跨域的配置信息),
        //      然后我们在new CorsConfigurationSource()的时候,发现它是一个接口,
        //      所以我们要new他的实现类(双击选中类名,然后ctrl+h来看他的实现类)
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        //第6步: 创建一个配置CorsConfiguration对象
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        //第7步: 配置跨域(也就是在响应里面添加上支持跨域的字段)
        corsConfiguration.addAllowedHeader("*");//允许哪些头跨域,*代表允许任意头跨域
        corsConfiguration.addAllowedMethod("*");//允许哪些请求方式跨域,*代表允许任意请求方式跨域
        //注意: 当setAllowCredentials为true时.addAllowedOrigin("*")不能包含特殊值"*",不然报500错误,可以使用.addAllowedOriginPattern("*")代替
        corsConfiguration.addAllowedOriginPattern("*");//允许哪些请求来源跨域,*代表任意请求来源跨域
        corsConfiguration.setAllowCredentials(true);//是否允许携带cookie进行跨域,true为允许
        //第5步: 注册跨域的配置: 第一个参数是路径,第二个参数还是一个配置: CorsConfiguration config
        source.registerCorsConfiguration("/**",corsConfiguration);//任意路径我们都需要跨域配置
        //第3步: 这个filter要进行一个配置,先new一个跨域的filter: CorsWebFilter
        //      在new完之后下面飘红线,点进去之后发现这个filter的构造器里面需要一个参数,这个参数就是跨域的配置信息: CorsConfigurationSource configSource
        return new CorsWebFilter(source);
    }
}
